#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include "StdTcp.h"



struct StdTcpServer
{
    int sock;
};
TcpS *  TcpServerInit(const char *ip, unsigned short port)
{   
    TcpS*s = (TcpS*)malloc(sizeof(TcpS));
    if(s == NULL)
    {
        printf("Tcps malloc error!\n ");
        return NULL;
    }
    
    s->sock = socket(AF_INET,SOCK_STREAM,0);
    if(s->sock < 0)
    {
        printf("Tcps malloc error\n");
        return NULL;
    }
    
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);
    if(bind(s->sock,(struct sockaddr*)&addr,sizeof(addr)) < 0)
    {
        perror("bind");
        free(s);
        return NULL;
    }

    int on = 1;
    if(setsockopt(s->sock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0)
    {
        perror("setsockopt");
         free(s);
        return NULL;
    }

    if(listen(s->sock,10) < 0)
    {
        perror("listen");
        free(s);
        return NULL;
    }
   return s;
}

int TcpServerAccept(TcpS * s)
{
    struct sockaddr_in clientAddr;
    socklen_t len = sizeof(clientAddr);
    int clientSock = accept(s->sock,(struct sockaddr*)&clientAddr,&len);
    if(clientSock < 0)
    {
        perror("accept");
        return -1;
    }
    return clientSock;

}

bool TcpServerSend(int clientSock, void *p, size_t size)
{   
    if(send(clientSock,p,size,0) < 0)
    {
        perror("send");
        return false;
    }
    return true;
}

bool TcpServerRecv(int clientSock, void *p, size_t size)
{  
    if(recv(clientSock,p,size,0) <=0 )
    {
        perror("recv");
        return false;
    }
    return true;
}

void ClearTcpServer(TcpS *s)
{
    close(s->sock);
    free(s);
}


struct StdTcpClient
{
    int sock;
};

TcpC *TcpClientInit(const char *ServerIP, unsigned short ServerPort)
{   
    TcpC *c = (TcpC*)malloc(sizeof(TcpC));
    if(c == NULL)
    {
        printf("TcpC malloc error!\n");
        return NULL;
    }
    
    c->sock = socket(AF_INET,SOCK_STREAM,0);
    if(c->sock < 0)
    {
        perror("socket");
        free(c);
        return NULL;
    }
    
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(ServerPort);
    addr.sin_addr.s_addr = inet_addr(ServerIP);
    if(connect(c->sock,(struct sockaddr*)&addr,sizeof(addr))<0)
    {
        perror("connect");
        free(c);
        return NULL;
    }

    return c;
}

bool TcpClientSend(TcpC *c, void *p, size_t size)
{   
    if(send(c->sock,p,size,0)<0)
    {
        perror("send");
        return false;

    }
    return true;
}

bool TcpClientRecv(TcpC *c, void *p, size_t size)
{   
    if(recv(c->sock,p,size,0) <= 0)
    {
        perror("recv");
        return false;
    }
    return true;
}

void ClearTcpClient(TcpC *c)
{
    close(c->sock);
    free(c);
}
